package com.googlecode.groovy_toy_orm

import com.googlecode.groovy_toy_orm.internal.Util


/**
 * @author: DavydovMD
 * Date: 10.04.13
 * Time: 11:08
 */
enum ConditionOp {
    EQ(" = "), NEQ(' <> '), GT(' > '), LT('<'), GTE(' >= '), LTE(' <= '), IN(' IN '), NOT_IN(' NOT IN '), IS_NULL(' IS NULL '), IS_NOT_NULL(' IS NOT NULL ') , BTEQ (" bitwise eq "), BTNEQ(' bitwise neq ')

    String sqlExpression


    ConditionOp(def sqlExpr) {
        sqlExpression = sqlExpr
    }

    public GString buildSql(def value) {
        if ([IN, NOT_IN].contains(this)) {
            if (value) {
                return Util.asGString(SqlMappingUtil.buildInClause(this, value as List))
            } else
                return this == IN ?Util.asGString(" IN (NULL /* IN(EMPTY_SET) */)  ") :Util.asGString(" + NULL IS NULL /* NOT_IN(EMPTY_SET) */  ")
        } else if ([IS_NULL, IS_NOT_NULL].contains(this)) {
            return Util.asGString(sqlExpression)
        }
        else if (this==BTEQ){
            return " & ${value} <> 0 "
        } else if (this==BTNEQ){
            return " & ${value} = 0 "
        }
        else {
            if (value instanceof FieldReference) {
                return Util.asGString(sqlExpression).plus(value.getFqn())
            } else
                return Util.asGString(sqlExpression).plus(" ${value} ")
        }
    }

    public boolean apply(def left, right) {
        switch (this) {

            case EQ:
                return left == right
            case NEQ:
                return left != right
            case GT:
                return left > right
            case LT:
                return left < right
            case GTE:
                return left >= right
            case LTE:
                return left <= right
            case IN:
                return right.contains(left)
            case NOT_IN:
                return !right.contains(left)
            case IS_NULL:
                return left == null
            case IS_NOT_NULL:
                return left != null
        }
        throw new UnsupportedOperationException("Этого не умеем: ${left} ${this} ${right}")
    }

}
